package com.panshi.controller;


import com.alibaba.fastjson.JSONArray;
import com.google.code.kaptcha.Producer;
import com.panshi.api.UserApi;
import com.panshi.shiro.PhoneEmailToken;
import com.panshi.vo.R;
import com.panshi.vo.UserNoticeRead;
import com.panshi.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.regex.Pattern;

@Slf4j
@Controller
@CrossOrigin
public class LoginController {

    @Autowired
    private Producer kaptchaProducer;

    @Autowired
    private UserApi userApi;

    @GetMapping("/login")
    public String toLogin(@RequestParam(value = "isd",required = false) Integer isd, Model model){
        model.addAttribute("isd",isd);
        return "login";
    }

    @GetMapping("/register")
    public String register(@RequestParam(value = "isd",required = false) Integer isd, Model model){
        model.addAttribute("isd",isd);
        return "register";
    }

    @PostMapping("/login")
    @ResponseBody
    public R login(@Validated @RequestBody UserVO userVO, HttpSession session,HttpServletResponse response){
        AuthenticationToken token = null;
        Subject subject = SecurityUtils.getSubject();
        if(userVO.getPassword() == "" ){
            token = new PhoneEmailToken(userVO.getUsername(),userVO.getVerifyCode());

        }else {
            String kaptcha = (String)session.getAttribute("kaptcha");
            if(null == kaptcha || !(kaptcha.equalsIgnoreCase( userVO.getVerifyCode()))){
                return R.error().msg("验证码错误~~~1");
            }
            token = new UsernamePasswordToken(userVO.getUsername(),userVO.getPassword());
        }

        try{
            subject.login(token);
            Object obj = userApi.getUserId(userVO.getUsername()).getData().get("userId");
            session.setAttribute(session.getId(),obj);
            Cookie cookie = new Cookie("SESSION", session.getId());
            response.addCookie(cookie);
            return R.ok().msg("登录成功");
        }catch(UnknownAccountException e){
            e.printStackTrace();
            return R.error().msg("账号不存在");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            return R.error().msg("密码错误");
        }catch (Exception e){
            e.printStackTrace();
            return R.error().msg("登录异常,请稍后再试");
        }
    }

    @PostMapping("/register")
    @ResponseBody
    public R reg(@Validated @RequestBody UserVO userVO, HttpSession session,HttpServletResponse response) throws IOException {

        R r = userApi.userRegister(userVO);
        if(r.isSuccess()){
            Object obj = r.getData().get("data");

            session.setAttribute(session.getId(),obj);
            Cookie cookie = new Cookie("SESSION", session.getId());
            response.addCookie(cookie);
        }
        return  r;
    }

    /**
     * 验证码
     * @param response
     * @param session
     */
    @GetMapping(path = "/kaptcha")
    public void getKaptcha(HttpServletResponse response, HttpSession session) {
        // 生成验证码
        String text = kaptchaProducer.createText();
        BufferedImage image = kaptchaProducer.createImage(text);

        // 将验证码存入session
        session.setAttribute("kaptcha", text);

        // 将突图片输出给浏览器
        response.setContentType("image/png");
        try {
            OutputStream os = response.getOutputStream();
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            log.error("响应验证码失败:" + e.getMessage());
        }
    }

    /**
     * 短信验证码
     */
    @PostMapping("/sendCodeLogin")
    @ResponseBody
    public R sendCodeLogin( UserVO userVO ,HttpSession session){
        String code = (String)session.getAttribute("kaptcha");

        if(code == null|| !(code.equalsIgnoreCase( userVO.getVerifyCode()))){
            return R.error().msg("验证码错误===2");
        }

        R r = userApi.verifyCode(userVO.getUsername());
        return R.error().msg(r.getMsg());
    }

    /**
     * 短信和邮箱验证码
     */
    @PostMapping("/sendCodeRegister")
    @ResponseBody
    public R sendCodeRegister( UserVO userVO ,HttpSession session){
        String code = (String)session.getAttribute("kaptcha");
        if(code == null|| !(code.equalsIgnoreCase( userVO.getVerifyCode()))){
            return R.error().msg("验证码错误===3");
        }

        R r = userApi.verifyCodeRegitser(userVO.getUsername());
        return r;
    }

    //是否登录
    @RequestMapping("/islogin")
    @ResponseBody
    public R islogin(HttpSession httpSession){
        Integer userId=(Integer)httpSession.getAttribute(httpSession.getId());
        if(userId != null){
            return R.ok();
        }else{
            return R.error();
        }
    }

    //退出登录
    @RequestMapping("/login/out")
    @ResponseBody
    public R loginOut(HttpSession httpSession){
        httpSession.removeAttribute(httpSession.getId());
        Integer userId=(Integer)httpSession.getAttribute(httpSession.getId());
        if(userId == null){
            return R.ok();
        }else{
            return R.error();
        }
    }

    //站内消息各个类型未读数
    @RequestMapping("/user/center/getNoReadCount")
    @ResponseBody
    public  List<UserNoticeRead>  noReadCount(HttpSession httpSession){

        Integer userId=(Integer)httpSession.getAttribute(httpSession.getId());
        if(userId == null){
            return null;
        }

        Object data = userApi.getNoReadCount(userId).getData().get("data");

        List<UserNoticeRead> userNoticeReads = JSONArray.parseArray(data.toString(), UserNoticeRead.class);
        return userNoticeReads;
    }
}
